home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / prog / amisl090.zip / UNINSTAL.ASM < prev    next >
Assembly Source File  |  1992-09-12  |  8KB  |  308 lines

  1. ;-----------------------------------------------------------------------
  2. ; Alternate Multiplex Interrup Specification Library
  3. ; AMIS.ASM    Public Domain 1992 Ralf Brown
  4. ;        You may do with this software whatever you want, but
  5. ;        common courtesy dictates that you not remove my name
  6. ;        from it.
  7. ;
  8. ; Version 0.90
  9. ; LastEdit: 9/12/92
  10. ;-----------------------------------------------------------------------
  11.  
  12.     INCLUDE AMIS.MAC
  13.  
  14. ;-----------------------------------------------------------------------
  15.  
  16. _TEXT SEGMENT PUBLIC BYTE 'CODE'
  17.     ASSUME    CS:_TEXT
  18.  
  19. ;-----------------------------------------------------------------------
  20.  
  21. resident_seg    dw 0    ; location of TSR code after relocation
  22. alloc_strat    dw 0
  23. link_state    db 0    ; are UMBs part of memory chain?
  24.  
  25. ;-----------------------------------------------------------------------
  26. ; Call the XMS driver
  27. ;
  28. ; entry: all registers as needed for XMS call
  29. ; exit:     registers as returned by XMS driver
  30. ;     ZF set if successful, ZF clear if failure
  31. ;
  32. XMS proc near
  33.     db    09Ah    ; FAR CALL
  34. xms_entry dd    0    ; XMS driver's entry point
  35.     cmp    ax,1
  36.     ret
  37. XMS endp
  38.  
  39. ;-----------------------------------------------------------------------
  40. ; Determine entry point of XMS driver and initialize procedure XMS to call
  41. ; that entry point
  42. ;
  43. ; exit: CF set if no XMS driver or other failure
  44. ;    CF clear if initialization successful
  45. ;
  46. get_XMS_entry proc near
  47.     push    es
  48.     mov    ax,352Fh
  49.     int    21h            ; find out whether INT 2F is valid
  50.     mov    ax,es
  51.     or    ax,bx            ; don't try XMS if INT 2F is NULL
  52.     jz    no_XMS_driver        ; (could be case under DOS 2.x)
  53.     mov    ax,4300h        ; see if XMS is installed
  54.     int    2Fh
  55.     cmp    al,80h            ; did XMS respond?
  56.     jnz    no_XMS_driver
  57.     mov    ax,4310h        ; if XMS present, get its entry point
  58.     int    2Fh
  59.     mov    word ptr xms_entry,bx
  60.     mov    word ptr xms_entry+2,es ; and store entry point for call
  61.     pop    es
  62.     clc
  63.     ret
  64. no_XMS_driver:
  65.     pop    es
  66.     stc
  67.     ret
  68. get_XMS_entry endp
  69.  
  70. ;-----------------------------------------------------------------------
  71. ; entry: nothing
  72. ; exit:     CF set if not available, clear if available
  73. ;     AX,BX,CX,DX destroyed
  74. ;     if available, DOS5 UMBs have been linked into the memory chain
  75. ;
  76. check_if_DOS5_UMBs proc near
  77.     mov    ax,5800h
  78.     int    21h            ; get current allocation strategy
  79.     mov    alloc_strat,ax        ;   and remember it for later restore
  80.     mov    ax,5802h        ; get current state of UMB linkage
  81.     int    21h
  82.     mov    link_state,al
  83.     mov    ax,3000h        ; get DOS version
  84.     int    21h
  85.     cmp    al,5            ; DOS 5.0 or higher?
  86.     jb    no_DOS5_UMBs
  87.     cmp    al,10            ; but make sure not OS/2 penalty box
  88.     jae    no_DOS5_UMBs
  89.     mov    ax,2B01h
  90.     mov    cx,4445h
  91.     mov    dx,5351h
  92.     int    21h            ; check if DESQview running
  93.     cmp    al,0FFh            ; if yes, no UMB's to be allocated
  94.     jne    no_DOS5_UMBs
  95.     mov    ax,5803h
  96.     mov    bx,1            ; try to link in UMBs
  97.     int    21h
  98.     mov    ax,5802h        ; get new link state
  99.     int    21h
  100.     cmp    al,1
  101.     jne    no_DOS5_UMBs
  102.     clc                ; yes, we have UMBs
  103.     ret
  104.  
  105. no_DOS5_UMBs:
  106.     stc
  107.     ret
  108. check_if_DOS5_UMBs endp
  109.  
  110. ;-----------------------------------------------------------------------
  111. ; entry: DS:SI -> hooked interrupt list
  112. ; exit:     AX, BX, CX, DX destroyed
  113. ;     CF set if unable to unhook all vectors
  114. ;     CF clear if successful
  115. ;
  116. public unhook_interrupts
  117. unhook_interrupts proc DIST
  118.     push    es
  119.     push    ds
  120.     push    di
  121.     push    si
  122.     cld
  123. chk_unhook_loop:
  124.     lodsb
  125.     mov    dx,[si]            ; get offset of interrupt handler
  126.     inc    si            ;   and skip that field in the hook
  127.     inc    si            ;   list
  128.     cmp    al,2Dh
  129.     je    all_unhookable
  130.     mov    ah,35h
  131.     int    21h            ; get interrupt vector
  132.     mov    ax,es
  133.     mov    cx,ds
  134.     cmp    ax,cx            ; check segment agains of vectors
  135.     jne    chk_isp_loop
  136.     cmp    dx,bx            ; check offset of vector against ours
  137.     je    chk_unhook_loop        ; this int is unhookable if same
  138. chk_isp_loop:
  139.     cmp    word ptr es:[bx],10EBh    ; handler starts with JMP SHORT $+12 ?
  140.     jne    not_unhookable
  141.     cmp    word ptr es:[bx+6],424Bh ; valid signature?
  142.     jne    not_unhookable
  143.     cmp    byte ptr es:[bx+9],0EBh ; hardware reset must also be JMP SHORT
  144.     jne    not_unhookable
  145.     cmp    cx,word ptr es:[bx+4]    ; check segment of next ptr against ours
  146.     jne    chk_next_isp
  147.     cmp    dx,word ptr es:[bx+2]    ; check offset of next ptr against ours
  148.     je    chk_unhook_loop        ; this int is unhookable if same
  149. chk_next_isp:
  150.     les    bx,es:[bx+2]        ; advance to next ISP header
  151.     jmp    chk_isp_loop        ;   and test it
  152.  
  153. not_unhookable:
  154.     stc
  155. unhook_ints_done:
  156.     pop    di
  157.     pop    si
  158.     pop    ds
  159.     pop    es
  160.     ret
  161.  
  162. all_unhookable:
  163.     pop    si            ; get back start of hook list
  164.     push    si            ; and preserve SI for return
  165. unhook_loop:
  166.     lodsb
  167.     mov    dx,[si]
  168.     inc    si
  169.     inc    si
  170.     push    ds
  171.     push    ax
  172.     mov    ah,35h
  173.     int    21h            ; get interrupt vector
  174.     mov    ax,es
  175.     mov    cx,ds
  176.     cmp    ax,cx            ; check segments of vectors
  177.     jne    isp_loop
  178.     cmp    dx,bx            ; check offsets of vectors
  179.     jne    isp_loop
  180.     lds    dx,[bx+2]        ; get our old_int?? pointer
  181.     pop    ax
  182.     push    ax
  183.     mov    ah,25h            ; set interrupt vector
  184.     int    21h
  185.     jmp short unhooked_interrupt
  186. isp_next:
  187.     les    bx,es:[bx+2]        ; advance to next ISP header
  188. isp_loop:
  189. ;
  190. ; no need to check for a valid ISP header, as we already know all chains reach
  191. ; our header before non-ISP code
  192. ;
  193.     cmp    cx,es:[bx+4]        ; check segment of 'previous' ptr
  194.     jne    isp_next
  195.     cmp    dx,es:[bx+2]        ; check offset of 'previous' ptr
  196.     jne    isp_next
  197.     xchg    bx,dx
  198.     lds    bx,[bx+2]
  199.     xchg    bx,dx            ; ES:BX -> previous ISP
  200.                     ; DS:DX -> next ISP
  201.     mov    es:[bx+2],dx        ; prev->next = curr->next
  202.     mov    es:[bx+4],ds        ;    thus, we are now unhooked
  203. unhooked_interrupt:
  204.     pop    ax
  205.     pop    ds
  206.     cmp    al,2Dh
  207.     jne    unhook_loop
  208.     clc                ; indicate success
  209.     jmp    unhook_ints_done
  210. unhook_interrupts endp
  211.  
  212. ;-----------------------------------------------------------------------
  213. ; entry: AX = segment of TSR code within the calling executable
  214. ; exit:     CF clear if successful
  215. ;     CF set on error
  216. ;
  217. public _AMIS_uninstall
  218. _AMIS_uninstall proc DIST
  219.     push    bp
  220.     mov    bp,sp
  221. ifidni <DIST>,<FAR>
  222.  @mpx_number = byte ptr [bp+6]
  223. ELSE
  224.  @mpx_number = byte ptr [bp+4]
  225. ENDIF
  226.     ;
  227.     ; first, see whether the TSR can uninstall itself
  228.     ;
  229.     mov    ah,@mpx_number
  230.     mov    al,2
  231.     mov    dx,cs            ; load return address for success
  232.     mov    bx,offset _TEXT:uninstall_successful
  233.     int    2Dh
  234.     cmp    al,0FFh            ; successful?
  235.     je    uninstall_successful
  236.     cmp    al,02h          ; unsupp, unsucc, or unable to remove?
  237.     jbe     uninstall_done
  238.     cmp    al,05h            ; unknown return code?
  239.     jae    uninstall_failed
  240.     ;
  241.     ; TSR said it is safe to uninstall, but not able to do so itself,
  242.     ; so now we unhook its interrupts and free its memory
  243.     ;
  244.     mov    resident_seg,bx        ; remember which memory block to free
  245.     mov    ah,@mpx_number
  246.     mov    al,4
  247.     mov    bl,0            ; start with INT 00h
  248.     int    2Dh
  249.     cmp    al,1            ; function unsupported or can't determine?
  250.     jbe    uninstall_failed
  251.     cmp    al,4
  252.     jne    uninstall_failed    ; sorry, can't handle returns 02h/03h yet
  253. go_uninstall:
  254.     push    ds
  255.     push    si
  256.     mov    ds,dx            ; DS:SI -> hook list
  257.     mov    si,bx
  258.     call    unhook_interrupts
  259.     pop    si
  260.     pop    ds
  261.     jc    uninstall_failed
  262.     cmp    resident_seg,0B000h    ; regular DOS memblk if below video
  263.     jae    uninstall_highmem
  264.     mov    es,resident_seg
  265.     mov    ah,49h            ; free memory block
  266.     int    21h
  267. uninstall_successful:
  268.     mov    al,0FFh            ; indicate success
  269.     jmp short uninstall_done
  270. uninstall_failed:
  271.     mov    al,1            ; status = unsuccessful
  272. uninstall_done:
  273.     mov    ah,0            ; return AX=uninstall status code
  274.     pop    bp
  275.     ret
  276.  
  277. uninstall_highmem:
  278.     call    check_if_DOS5_UMBs    ; check if UMBs, and link them in
  279.     jc    uninstall_XMS
  280.     mov    es,resident_seg        ; free the memory block
  281.     mov    ah,49h
  282.     int    21h
  283. restore_link_state:
  284.     mov    ax,5801h
  285.     mov    bx,alloc_strat        ; restore allocation strategy
  286.     int    21h
  287.     mov    ax,5803h        ; and restore UMB link status
  288.     mov    bh,0
  289.     mov    bl,link_state
  290.     int    21h
  291.     jmp    uninstall_successful
  292.  
  293. uninstall_XMS:
  294.     call    get_XMS_entry
  295.     jc    uninstall_failed    ; no XMS driver!?!?!
  296.     mov    ah,11h            ; release UMB
  297.     mov    dx,resident_seg
  298.     call    XMS
  299.     jne    uninstall_failed    ; we deallocation successful?
  300.     jmp    uninstall_successful
  301. _AMIS_uninstall endp
  302.  
  303. ;-----------------------------------------------------------------------
  304.  
  305. _TEXT ENDS
  306.     END
  307.  
  308.